
//
//  PieView.m
//  YQPieView
//
//  Created by 杨琴 on 16/8/25.
//  Copyright © 2016年 杨琴. All rights reserved.
//

#import "PieView.h"

@implementation PieModel

- (instancetype)initWithVaule:(CGFloat)vaule color:(UIColor *)color {
    if (self = [super init]) {
        self.value = vaule;
        self.color = color;
    }
    
    return self;
}

@end

// 代表每一个扇形
@interface SliceLayer : CAShapeLayer

@property (nonatomic, assign) CGFloat startAngle;
@property (nonatomic, assign) CGFloat endAngle;
@property (nonatomic, strong) UIColor * color;
@property (nonatomic, assign) BOOL  selected; // 是否处于选中状态
@property (nonatomic, assign) CGPoint originPostion; // 记录初始位置

@end

@implementation SliceLayer

- (instancetype)initWithStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle color:(UIColor *)color centerPoint:(CGPoint)centerPoint radius:(CGFloat)radius {
    if (self = [super init]) {
        self.startAngle = startAngle;
        self.endAngle = endAngle;
        self.color = color;
        
        // 确定扇形路径
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:centerPoint];
        [path addArcWithCenter:centerPoint radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
        self.path = path.CGPath;
        self.fillColor = color.CGColor;
        self.lineWidth = 0;

    }
    
    return self;
    
}


@end

@interface PieView ()

@property (nonatomic, assign) CGPoint pieCenter; //饼状图的中心位置
@property (nonatomic, assign) CGFloat pieRadius;  // 饼状图的半径
@property (nonatomic, strong) CAShapeLayer * maskLayer; // 遮罩图层
@property (nonatomic, strong) NSMutableArray * sliceLayerArray; // 保存所有扇形图层

@end
@implementation PieView

- (instancetype)initWithFrame:(CGRect)frame pieModels:(NSArray<PieModel *> *)pieModelArray offset:(CGFloat)offset {
    if (self = [super initWithFrame:frame]) {
        self.pieModelArray = pieModelArray;
        self.offSet = offset;
        [self initializeDatas];
        [self setupUserInterface];
        [self startanimation];

        // 添加点击手势
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
        [self addGestureRecognizer:tap];
        
    }
    return self;
    
}

- (void)initializeDatas {
    self.pieCenter = CGPointMake(CGRectGetWidth(self.bounds) / 2, CGRectGetHeight(self.bounds)/2);
    self.pieRadius = MIN(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) / 2 - self.offSet;
}

- (void)setupUserInterface {
    
    CGFloat totalValue = [[self.pieModelArray valueForKeyPath:@"@sum.value"] floatValue];
    
    CGFloat currentAngle = 0;
    for (PieModel *modle  in self.pieModelArray) {
        // 每个扇形的百分比
        CGFloat percent = modle.value / totalValue;
        CGFloat startAngle = currentAngle;
        CGFloat endAngle = currentAngle + percent * 2 * M_PI;
        currentAngle = endAngle;
        SliceLayer *layer = [[SliceLayer alloc] initWithStartAngle:startAngle endAngle:endAngle color:modle.color centerPoint:self.pieCenter radius:self.pieRadius];
        [self.layer addSublayer:layer];
        
        layer.originPostion = layer.position;
        
        [self.sliceLayerArray addObject:layer];
    }
    
}

- (void)startanimation {
    self.layer.mask = self.maskLayer;
    
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = 5;
    animation.fromValue = @0;
    animation.toValue = @1;
    // 控制动画结束的时候会不会以动画结束的值来影响做动画的图层
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    // 设置代理用于监听动画执行完成
    animation.delegate = self;
    
    [self.maskLayer addAnimation:animation forKey:@"makeAnimation"];
}

#pragma mark - Action

- (void)tapAction:(UITapGestureRecognizer *)gesture {
    // 获取点击的点的位置
    CGPoint tapPoint = [gesture locationInView:self];
    SliceLayer *selectLayer = nil;
    for (SliceLayer *layer in self.sliceLayerArray) {
        if (CGPathContainsPoint(layer.path, NULL, tapPoint, NO)) {
            selectLayer = layer;
            break;
        }
    }
    
    if (selectLayer != nil) {
        selectLayer.selected = !(selectLayer.selected);
        
        [self offSetWithLayer:selectLayer];
    }
    
}

// 让选择的layer进行偏移
- (void)offSetWithLayer:(SliceLayer *)layer {
    if (layer.selected) {
        
        CGFloat angle = (layer.endAngle + layer.startAngle) / 2;
        CGFloat offsetX = self.offSet * cos(angle);
        CGFloat offsetY = self.offSet * sin(angle);
        
        CGPoint toPosion = CGPointMake(layer.position.x + offsetX, layer.position.y + offsetY);
        layer.position = toPosion;
        
    } else {
        layer.position = layer.originPostion;
    }
   
    
}

#pragma mark - animation delegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (anim == [self.maskLayer animationForKey:@"makeAnimation"]) {
        //移除遮罩
        self.layer.mask = nil;
    }
    
}

#pragma mark - Public
- (void)reloadDatas {
    
    for (SliceLayer *layer in self.sliceLayerArray) {
        [layer removeFromSuperlayer];
    }
    
    // 清空数组
    [self.sliceLayerArray removeAllObjects];
    
    [self initializeDatas];
    [self setupUserInterface];
    [self startanimation];
}

# pragma mark - Getter

- (CAShapeLayer *)maskLayer {
    if (_maskLayer == nil) {
        _maskLayer = [CAShapeLayer layer];
        
        UIBezierPath *path = [[UIBezierPath alloc] init];
//        [path moveToPoint:self.pieCenter];
        [path addArcWithCenter:self.pieCenter radius:self.pieRadius / 2 startAngle:0 endAngle:2 * M_PI clockwise:YES];
        _maskLayer.path = path.CGPath;
        _maskLayer.lineWidth = self.pieRadius;
        _maskLayer.strokeColor = [UIColor grayColor].CGColor;
        _maskLayer.fillColor = [UIColor clearColor].CGColor;
        _maskLayer.lineCap = kCALineCapButt;
        _maskLayer.strokeStart = 0;
        _maskLayer.strokeEnd = 0;
    }
    return _maskLayer;
}

- (NSMutableArray *)sliceLayerArray {
    if (_sliceLayerArray == nil) {
        _sliceLayerArray = [NSMutableArray array];
    }
    
    return _sliceLayerArray;
}

@end
















